ЗМІСТ
Введення
1 Постановка завдання
2 Математичні та алгоритмічні основи рішення задачі
3 Функціональні моделі та блок-схеми виконання завдання
4 Програмна реалізація рішення задачі
5 Приклад виконання програми
Висновок
Список використаних джерел та літератури
Введення
Гра «морський бій» досить добре відома і популярна. Практично кожен школяр у той чи інший період свого життя грав у цю гру. В останні роки у зв'язку з появою комп'ютерів і нових навчальних і розвиваючих програм знову зріс інтерес до неї. Якщо набрати запит про пошук гри в Інтернет, то пошукова машина видасть декілька тисяч посилань. Тут і реклама, і різні варіанти гри, і якісні дослідження оптимальних стратегій гри і т.д. Але мало хто знає про те, що ця гра має серйозне наукове і практичне застосування, і для її аналізу можуть бути використані сучасні математичні та комп'ютерні методи. Як приклад такого додатка можна навести проблему ефективного пошуку записів у великих базах даних, які мають складною багаторівневою структурою.
Зупинимося на деяких основних правилах класичного варіанту гри. Перший гравець, гравець А, розставляє кораблі на квадратному ігровому полі з n клітин (зазвичай це поле клітин). Кораблі діляться на класи: одноклітинні, двухклеточного, трехклеточние і четирехклеточние. Гравець В на своєму полі розставляє свої кораблі. Зауважимо, що кораблі не повинні торкатися один одного. Гра полягає в тому, що гравці по черзі називають координати клітин, в яких, як вони припускають, розташовані кораблі супротивника, тобто як би роблять постріл з обраної клітці. Про попадання або промаху гравцеві повідомляється після пострілу. Гра продовжується до тих пір, поки у одного з гравців не будуть знищені всі кораблі.
На перший погляд, ця гра носить чисто імовірнісний характер, так як гравці ведуть обстріл, не знаючи розташування кораблів супротивника. Але, придбавши деякий досвід гри, можна помітити, що існують стратегії розстановки кораблів, які зменшують імовірність потрапляння в останній одноклітинний корабель. Наприклад, можна розташувати весь флот таким чином, щоб він займав мінімальне місце на ігровому полі, а один або два кораблі ставлять на останньому просторі як на малюнку 1. Пошук кораблів також можна проводити, дотримуючись певної системи, яка дозволяє найбільш швидко виявити на початку гри багатоклітинні кораблі, а потім на останньому просторі шукати одноклітинні кораблі.
Малюнок 1
Ці якісні міркування показують, що у гравців А і В існує безліч нерівнозначних різних стратегій гри, тобто може бути поставлено питання про пошук оптимальних стратегій.
Зауважимо, що все це різноманітність стратегій, як це буде показано нижче, визначається правилом, що забороняє ставити кораблі впритул, а також правилом закінчення гри.
Надалі будемо розглядати тільки односторонню гру: гравець А розставляє кораблі, а гравець В веде їх пошук.
Математичну модель гри можна будувати двома способами. Перший спосіб полягає в тому, що після кожного пострілу враховуються зміни поля гри та ймовірності виявлення кораблів. Така форма гри називається розгорнутої, а сама гра представляється багатокрокової. Складність застосування цього підходу пов'язана з необхідністю визначення ймовірностей подій, які є комбінацією великого числа елементарних подій. При збільшенні числа пострілів k кількість комбінацій зростає пропорційно k! (Факторіалі k).
Другий спосіб полягає в тому, що в якості початкового безлічі подій розглядається безліч стратегій, елементи яких представляють повну послідовність n пострілів. У цьому випадку гра стає однокрокової, тобто гравець робить вибір не однієї клітини при пострілі, а вибирає послідовність з n пострілів. Така форма гри називається нормальною. Другий підхід до побудови гри носить інтегральний характер, однак, в цьому випадку виникає проблема, пов'язана з поняттям закінчення гри.
1. Постановка завдання
Завдання полягає в розробці алгоритму, за яким комп'ютер зможе грати в «Морський бій» з максимальною якістю, і при цьому не підглядаючи розташування флоту гравця.
Додаткове і очевидне умова: при кожній новій грі незалежно від розміщення сил противника комп'ютер повинен грати по-різному, тобто його ходи повинні бути не передбачувані.
Необхідно згадати правила гри: учасники поєдинку роблять ходи по черзі, причому, якщо один з гравців потрапляє по кораблю суперника, то він отримує право наступного ходу. Якщо реалізувати пошук мети комп'ютером у вигляді окремої процедури, то треба якось навчити його запам'ятовувати результати минулих пострілів, щоб адекватно провести наступний. З цього факту випливає, що саме просте і раціональне вирішення цієї проблеми можна оформити у вигляді кінцевого автомата, найбільш точно описує послідовність дій.
Можна виділити три стани:
простріл ігрового поля по випадкових координатами до попадання по кораблю, після чого перехід у другу стан;
обстріл навколо підбитим осередку поля для визначення напрямку корабля (вертикальне чи горизонтальне), після чергового попадання - перехід в третій стан;
розстріл корабля в отриманому напрямку до повного його знищення, після чого перехід в перший стан.
І так, вся гра зациклена на трьох основних діях: простріл, обстріл і розстріл. Всі ці дії повинні продовжуватися до тих пір, поки в однієї зі сторін не будуть знищені всі кораблі.
Простріл
На цьому етапі комп'ютер повинен зловити будь-якої з кораблів противника. Для цього він буде стріляти по довільним незайнятим клітинам поля гравця. Набагато ефективніше спочатку розправитися з великими кораблями, тому вибираючи координати для пострілу треба перевіряти, що б у цій позиції міг розміститися найбільший з решти кораблів. Процес припиняється, як тільки відбудеться влучання. Позначимо підбиту частина корабля значенням «*», а промах «~» відповідної комірки поля. Якщо у гравця залишилися тільки однопалубні кораблі, то цим попаданням корабель знищений повністю і обстрілювати його немає сенсу. В іншому випадку треба перейти до другого стану.
Обстріл
На цьому кроці завдання полягає у визначенні напрямку спійманого корабля. Для цього треба обстріляти чотири осередки (якщо вони вільні), які можуть служити продовженням. У випадку, коли всі чотири клітини обстріляні, а потрапляння не відбулося (однопалубний корабель), треба перейти до першого стану. Якщо в якийсь момент вдалося підбити ще одну палубу супротивника, то можна переходить до розстрілу даного корабля, тому що його напрямок стало відомо. Аналогічно першому стану, якщо у гравця залишилися кораблі не більше двох палуб, то цим попаданням корабель знищений повністю і треба повернутися до прострілу.
Розстріл
На попередньому кроці вдалося встановити в якому напрямку розміщений спійманий корабель. Тепер завдання полягає в його повному знищенні. Для цього треба стріляти праворуч або ліворуч (зверху чи знизу) підбитих палуб, поки не доб'ємо його повністю, після чого повернемося в стан прострілу. При цьому слід враховувати максимально можливий корабель і намагатися потрапити по четвертій палубі, коли чотирьох палубний корабель знищений, немає ніякого сенсу.
Приклад
Поле кораблів
1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
1 |